"""
@author: wtf
@file: auth.py
@time: 2024/5/8 16:36
@desc: Authorization related view controllers
"""
import os
from datetime import datetime

from flask import Blueprint, render_template, jsonify, redirect, url_for, session, g
from werkzeug.utils import secure_filename
import config
from decorators import login_required
from exts import mail
from flask_mail import Message
from flask import request
from models import EmailCaptchaModel, UserModel, PhotosModel
from exts import db
from utils.util import send_photos, qiniu_delete_photos
from .forms import RegisterForms, LoginForms
import hashlib
import string
import random

bp = Blueprint("auth", __name__, url_prefix="/auth")  # url_prefix代表访问前缀


# 相当于127.0.0.1:5000/auth/login
@bp.route("/login", methods=["GET", "POST"])
def user_login():
    if request.method == "GET":
        return render_template("login.html")
    else:
        # 验证表单
        form = LoginForms(request.form)
        print(request.args.get("email"))
        print(form.email.data)
        print(form.password.data)
        if form.validate():
            user = UserModel.query.filter_by(email=form.email.data).first()
            if user:
                if hashlib.md5(form.password.data.encode()).hexdigest() == user.password:
                    session["user_id"] = user.id
                    return redirect("/")
                else:
                    return "密码错误"
            else:
                return "用户名不存在或密码错误!"
        else:
            print(form.errors)
            return "验证失败!"


# 退出登录
@bp.route("/logout")
def logout():
    session.clear()
    return redirect("/")


# GET:从服务器获取数据 POST:从提交数据给服务器
@bp.route("/register", methods=["GET", "POST"])
def register():
    if request.method == 'GET':
        return render_template("register.html")
    else:
        # 验证提交的表单
        form = RegisterForms(request.form)
        if form.validate():
            # 通过验证
            email = form.email.data
            username = form.username.data
            password = form.password.data
            # 对密码进行md5加密
            password_md5 = hashlib.md5(password.encode())
            # 转换为十六进制字符串
            password_md5_hash = password_md5.hexdigest()
            user = UserModel(email=email, username=username, password=password_md5_hash)
            db.session.add(user)
            db.session.commit()
            return redirect(url_for("auth.user_login"))  # url_for找到方法对应的路由
        else:
            print(form.errors)
            return render_template("register.html", error=form.errors)


# 发送验证码  默认get请求
@bp.route("/mail")
def send_mail():
    email = request.args.get("email")
    print(f"接受到的邮箱:{email}")
    source = string.digits * 4  # 40位长度的数字
    verification_code = random.sample(source, 4)  # 取4位
    verification_code = "".join(verification_code)
    print(f"生成的验证码是:{verification_code}")
    # 发送邮箱操作
    msg = Message(subject="邮箱验证码!", recipients=[email], body=verification_code)
    # mail.send(msg)
    # 邮箱后端存储 1.存储到Redis 2.存储到数据库 3.memcached
    # email_captcha = EmailCaptchaModel(email=email, captcha=verification_code)
    # db.session.add(email_captcha)
    # db.session.commit()
    return jsonify({"code": 200, "message": "null", "data": None})


@bp.route("/mail/test")
def send_mail_test():
    message = Message(subject="尊敬的汪婷你好!", recipients=["1306134542@qq.com"], body="你是猪",
                      sender="2416224351@qq.com")
    mail.send(message)
    return "邮件发送成功"


@bp.route("/confirm/pwd", methods=["GET", "POST"])
def confirm_pwd():
    if request.method == "GET":
        return render_template("user.html")
    else:
        user_id = request.form.get("id")
        password = request.form.get("old_password")
        print(user_id, password, "-------------------")
        user = UserModel.query.filter_by(id=user_id).first()
        print(user.username)
        if user:
            if user.password == hashlib.md5(password.encode()).hexdigest():
                return jsonify({"code": 200, "message": "success", "data": None})
            else:
                return jsonify({"code": 400, "message": "fail", "data": None})
        else:
            return jsonify({"code": 400, "message": "fail", "data": None})


# 修改信息
@bp.route("/update/message", methods=["GET", "POST"])
def update_message():
    new_pwd = request.form.get("new_password")
    file = request.files.get("photo")
    username = request.form.get("username")
    user_id = request.form.get("id")
    user = UserModel.query.filter_by(id=user_id).first()

    if file and file.filename.split(".")[-1] in ['jpg', 'png', 'jpeg', 'gif', 'bmp', 'webp', 'svg']:
        # 定义一个新文件名，这里假设你想保留原来的文件扩展名
        new_filename = secure_filename(
            str(datetime.now().timestamp()).split(".")[0] + username + '.' + file.filename.split('.')[-1])
        # 保存文件到指定的目录，这里假设是'app/static/uploads'
        file.save(os.path.join(config.PHOTO_DIR, new_filename))
        # 删除原来的照片
        if os.path.isfile(f".{user.photo}"):
            # 删除原来的文件
            os.remove(f".{user.photo}")
            print("remove__picture__ok!")
        user.photo = f"/static/photos/{new_filename}"
    if new_pwd:
        user.password = hashlib.md5(new_pwd.encode()).hexdigest()
        db.session.commit()
        # 退出登录
        return redirect(url_for("auth.logout"))
    else:
        db.session.commit()
        return render_template("user.html")


@bp.route("/show/photos", methods=["POST", "GET"])
@login_required
def show_photos():
    if request.method == "GET":
        page = int(request.args.get("page", 1))
        paginate = PhotosModel.query.filter_by(user_id=g.user.id).order_by(PhotosModel.join_time.desc()).paginate(page=page, per_page=8)
        return render_template("show_photos.html", paginate=paginate)
    else:
        # 获得照片对象""
        file = request.files.get("photo")
        if file and file.filename.split(".")[-1] in ['jpg', 'png', 'jpeg', 'gif', 'bmp', 'webp', 'svg']:
            # 定义一个新文件名，这里假设你想保留原来的文件扩展名
            new_filename = secure_filename(
                str(datetime.now().timestamp()).split(".")[0] + "_" + str(g.user.id) + '.' + file.filename.split('.')[
                    -1])
            # 保存到qiniu云
            ret, info, token = send_photos(file, new_filename)
            if info.status_code == 200:
                # 保存成功,保存到数据库
                photo = PhotosModel(photo_name=ret["key"], hash=ret["hash"], user_id=g.user.id)
                db.session.add(photo)
                db.session.commit()
                return redirect(url_for("auth.show_photos"))
        return "保存失败"

@bp.route("/delete/photos", methods=["POST"])
def delete_photos():
    if request.method == "POST":
        photo_id = int(request.form.get("photo_id"))
        photo = PhotosModel.query.filter_by(id=photo_id).first()

        if photo:
            # 从七牛云删除照片
            ret, info = qiniu_delete_photos(photo.photo_name)
            db.session.delete(photo)
            db.session.commit()
            return jsonify({"code": 200, "message": "success", "data": None})
        else:
            return jsonify({"code": 400, "message": "fail", "data": None})
